package com.psiqueware.alheli.seguridad.modelo;

/**
 * @(#)CredencialK.java 26-oct-2005
 *
 * Copyright (c) 2005-2010 Psiqueware S.A. de C.V. All Rights Reserved.
 * This software is the proprietary information Psiqueware S.A. de C.V.
 * Use is subject to license terms.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * <br/>Usuario : AngelElectrico
 * <br/>Creaci&oacute;n: 26-oct-2005
 * <br/>
 * <br/>
 * <br/><t5>Cambios :</t5>
 * <br/><b>Fecha | Autor  |  Cambios</b>
 * <br/>26-oct-2005 | <a href = "mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a> | Creaci&oacute;n del Objeto.
 * <li>Feb 4, 2007  | <a href = "mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a> | Se removio el identificador como SuperUsuario, a cambio al Usuario Presidente se le dara un Rol donde se inyectaran todos los Permisos.</li>
 */

import com.psiqueware.alheli.basico.BaseObject;
import com.psiqueware.alheli.exception.NullArgumentException;
import com.psiqueware.alheli.seguridad.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Identificaci&oacute;n de seguridad para un {@link UsuarioSeguridad}.
 * <br/>Paquete Original: com.psiqueware.basico.seguridad.modelo
 * <br/>Nombre  Original: CredencialK
 * <br/><a href="CredencialK.java.html"><i>Ver Fuente</i> </a>
 *
 * @author <a href="mailto:AngelElectrico@psiqueware.com">Angel El&eacute;ctrico</a>
 * @version Revision: 1.1 $ 26-oct-2005 18:21:50
 * @noinspection ClassWithoutLogger, ClassWithoutNoArgConstructor
 */
public final class CredencialK extends BaseObject implements Credencial
{


    /**
     * &Iacute;dentificador &uacute;nico de la {@link Agrupacion} al que pertenece esta {@link Credencial}.
     */
    private Long m_idAgrupacion;

    /**
     * {@link Agrupacion} al que pertenece esta {@link Credencial}.
     */
    private Agrupacion m_agrupacion;

    /**
     * Listado de {@link Rol} asignados a esta {@link Credencial}.
     */
    private final List<Rol> m_roles = new ArrayList<Rol>();

    /**
     * Identificador del UsuarioSeguridad que contiene esta credencial.
     * No deber&iacute;a utilizarse fuera de este m&oacute;dulo.
     */
    private Long m_idUsuarioSeguridad;

    /**
     * Nombre calificado de la clase implementadora de UsuarioSeguridad que contiene esta
     * {@link Credencial}.  No deber&iacute;a utilizarse fuera de este m&oacute;dulo.
     */
    private String m_nombreClaseUsuarioSeguridad;

    /**
     * Listado de {@link RolCredencial}s que que llevan la relaci&oacute;n de esta con su {@link com.psiqueware.alheli.seguridad.Rol}.
     */
    private final List<RolCredencial> m_rolesCredencial = new ArrayList<RolCredencial>();

    /**
     * Construye una CredencialK.
     * No requiere argumentos.
     * Se utiliza SOLO para hibernate.
     */
    public CredencialK()
    {

    }

    /**
     * Construye un CredencialK
     *
     * @param usuarioSeguridad al que va a pertenecer la credencial. Debe estar Persistido.
     *
     * @noinspection DuplicateStringLiteralInspection
     */
    public CredencialK(UsuarioSeguridad usuarioSeguridad)
    {
        if (null == usuarioSeguridad)
            throw new NullArgumentException("<error>El argumento 'usuarioSeguridad' no puede ser NULL.</error>");
        if (null == usuarioSeguridad.getId())
            throw new IllegalArgumentException("<error>El argumento 'usuarioSeguridad' deb&iacute;a encontrarse previamente persistido.</error>");
        this.m_idUsuarioSeguridad = usuarioSeguridad.getId();
        this.m_nombreClaseUsuarioSeguridad = usuarioSeguridad.getClass().getCanonicalName();
        usuarioSeguridad.setCredencial(this);
    }

    /**
     * Devuelve el {@link RolCredencial} para un {@link Rol} dado.
     *
     * @param rol Cuyo {@link RolCredencial} se busca.
     *
     * @return {@link RolCredencial} en caso de encontrarlo; <code>null</code> en caso contrario.
     */
    public RolCredencial buscaRolCredencial(final Rol rol)
    {
        for (final RolCredencial rolCredencial : m_rolesCredencial)
        {
            if (rolCredencial.getRol().equals(rol))
            {
                return rolCredencial;
            }
        }
        return null;
    }

    /**
     * A&ntilde;ade un {@link RolCredencial} al listado m_rolesCredencial, que que llevan la relaci&oacute;n de esta con su {@link com.psiqueware.alheli.seguridad.Rol}.
     *
     * @param o {@link RolCredencial} a añadir.
     *
     * @return <tt>true</tt> (as per the general contract of the
     * <tt>Collection.add</tt> method).
     */
    public boolean addRolCredencial(final RolCredencial o)
    {
        m_roles.add(o.getRol());
        return m_rolesCredencial.add(o);
    }

    /**
     * Remueve un {@link RolCredencial} del listado <code>m_rolesCredencial</code>, que que llevan la relaci&oacute;n de esta con su {@link com.psiqueware.alheli.seguridad.Rol}.
     *
     * @param rolCredencial {@link RolCredencial} a eliminar.
     *
     * @return <tt>true</tt> if this list contained the specified element.
     */
    public boolean removeRolCredencial(final RolCredencial rolCredencial)
    {
        if ( null == rolCredencial ) throw new NullArgumentException ( "<error>El argumento 'rolCredencial' no puede ser NULL.</error>" );
        m_roles.remove(rolCredencial.getRol());
        return m_rolesCredencial.remove(rolCredencial);
    }

    /**
     * Devuelve una copia del listado <code>m_rolesCredencial</code>, que que llevan la relaci&oacute;n de esta con su {@link com.psiqueware.alheli.seguridad.Rol}.
     *
     * @return una nueva List&lt;RolCredencial&gt;.
     */
    public List<RolCredencial> listRolCredencials()
    {
        return new ArrayList<RolCredencial>(m_rolesCredencial);
    }

    /**
     * Devuelve la Lista de los {@link RolCredencial} que que llevan la relaci&oacute;n de esta con su {@link com.psiqueware.alheli.seguridad.Rol}.
     *
     * @return List(unmodifiable) de 'm_rolesCredencial'.
     *
     * @see java.util.List
     */
    public List<RolCredencial> getRolCredencials()
    {
        return Collections.unmodifiableList(m_rolesCredencial);
    }

    /**
     * Establece los valores de la Lista de los {@link RolCredencial} que que llevan la relaci&oacute;n de esta con su {@link com.psiqueware.alheli.seguridad.Rol}.
     *
     * @param newList nuevo valor para 'm_rolesCredencial'. En caso de ser nulo se vaciar&aacute; el arreglo existente.
     *
     * @see java.util.List
     */
    public void setRolCredencials(final List<? extends RolCredencial> newList)
    {
        this.m_rolesCredencial.clear();
        m_roles.clear();
        if (null != newList)
        {
            for (final RolCredencial rolCredencial : newList)
            {
                addRolCredencial(rolCredencial);
            }
        }
    }

    /**
     * Nos dice si el {@link RolCredencial} se encuentra contenido en la
     * lista.
     *
     * @param o {@link RolCredencial} a buscar.
     *
     * @return <code>true</code> si lo encuentra; <code>false</code> en caso contrario.
     */
    public boolean containsRolCredencial(final RolCredencial o)
    {
        return m_rolesCredencial.contains(o);
    }

    /**
     * Nos dice si el {@link Rol} se encuentra contenido en la
     * lista.
     *
     * @param o {@link Rol} a buscar.
     *
     * @return <code>true</code> si lo encuentra; <code>false</code> en caso contrario.
     */
    public boolean containsRol(final Rol o)
    {
        return m_roles.contains(o);
    }


    /**
     * Devuelve una copia de la lista de los {@link Rol} que tiene este {@link Credencial}.
     *
     * @return lista de {@link Rol}.
     */
    public List<Rol> listRoles()
    {
        return new ArrayList<Rol>(m_roles);
    }

    /**
     * Dice si se pose&eacute; un {@link Permiso}.  Ya sea en un rolPrincipal rolCredencial en los roles asignados.
     *
     * @noinspection CastToConcreteClass
     */
    public boolean tienePermiso(Permiso permiso)
    {
        boolean salida = false;
        for (Rol rolFound : m_roles)
        {
            RolK rolK = (RolK) rolFound;
            if (rolK.tienePermiso(permiso))
            {
                salida = true;
                break;
            }

        }
        return salida;
    }

    /**
     * Devuelve el &Iacute;dentificador &uacute;nico de la {@link Agrupacion} al que pertenece esta {@link Credencial}.
     *
     * @return Valor de 'm_idAgrupacion'.
     */
    public Long getIdAgrupacion()
    {
        return m_idAgrupacion;
    }

    /**
     * Establece el &Iacute;dentificador &uacute;nico de la {@link Agrupacion} al que pertenece esta {@link Credencial}.
     *
     * @param idAgrupacion Nuevo valor para 'm_idAgrupacion'.
     */
    public void setIdAgrupacion(final Long idAgrupacion)
    {
        m_idAgrupacion = idAgrupacion;
    }

    /**
     * Establece el agrupacion al que pertenece esta credencial.
     *
     * @return agrupacion
     */
    public Agrupacion getAgrupacion()
    {
        return m_agrupacion;
    }

    /**
     * Devuelve el agrupacion al que pertenece esta credencial.
     *
     * @param agrupacion a la que pertenece esta Credencial.
     */
    public void setAgrupacion(Agrupacion agrupacion)
    {
        this.m_agrupacion = agrupacion;
        this.m_idAgrupacion = null == agrupacion ? null : agrupacion.getId();
    }

    /**
     * Deveuvle una lista de roles.
     * Solo se utilizan por Hibernate, no usar ni poner en la interfas.
     *
     * @return List
     *
     * @noinspection ReturnOfCollectionOrArrayField
     */
    public List<Rol> getRoles()
    {
        return m_roles;
    }

    /**
     * Devuelve el Identificador del UsuarioSeguridad que contiene esta credencial.
     * No deber&iacute;a utilizarse fuera de este m&oacute;dulo.
     *
     * @return valor de 'idUsuarioSeguridad'.
     */
    public Long getIdUsuarioSeguridad()
    {
        return m_idUsuarioSeguridad;
    }

    /**
     * Establece el Identificador del UsuarioSeguridad que contiene esta credencial.
     * No deber&iacute;a utilizarse fuera de este m&oacute;dulo.
     *
     * @param idUsuarioSeguridad nuevo valor para 'idUsuarioSeguridad'.
     */
    public void setIdUsuarioSeguridad(Long idUsuarioSeguridad)
    {
        m_idUsuarioSeguridad = idUsuarioSeguridad;
    }


    /**
     * Devuelve el Nombre calificado de la clase implementadora de UsuarioSeguridad que contiene esta
     * {@link Credencial}.
     *
     * @return valor de 'claseUsuarioSeguridad'.
     *
     * @see String
     */
    public String getNombreClaseUsuarioSeguridad()
    {
        return m_nombreClaseUsuarioSeguridad;
    }

    /**
     * Establece el Nombre calificado de la clase implementadora de UsuarioSeguridad que contiene esta
     * {@link Credencial}.
     *
     * @param cus nuevo valor para 'claseUsuarioSeguridad'.
     *
     * @see String
     */
    public void setNombreClaseUsuarioSeguridad(final String cus)
    {
        m_nombreClaseUsuarioSeguridad = cus;
    }

    /**
     * Convierte este {@link Credencial} a su representaci&oacute;n textual.
     *
     * @noinspection DuplicateStringLiteralInspection
     */
    public String toString()
    {

        StringBuilder sb = new StringBuilder();
        sb.append("<Instance Class = '").append(this.getClass().getName()).append("'>");
        sb.append("<id>").append(m_id).append("</id>");
        if (null == m_agrupacion)
        {
            sb.append("<agrupacion>").append(m_agrupacion).append("</agrupacion>");
        }
        else
        {
            sb.append("<agrupacion>").append(m_agrupacion.getId()).append("</agrupacion>");
        }
        sb.append("<roles size ='").append(m_roles.size()).append("'>");
        for (Rol rolFound : m_roles)
        {
            Rol rol = rolFound;
            sb.append("<rol>").append(rol.getNombre()).append("</rol>");
        }
        sb.append("</roles>");
        sb.append("</Instance>");
        return sb.toString();
    }
}
